home *** CD-ROM | disk | FTP | other *** search
- ;/* "C:Execute" me to compile me with SAS/C 6
- Set file StdIO-Handler
-
- sc:c/sc MOD NOICON VERBOSE STRMERGE UNSCHAR NOSTKCHK IGNORE=73 MOD CSRC $file.c
- sc:c/slink NOICONS FROM $file.o TO $file LIB lib:amiga.lib,lib:sc.lib,lib:debug.lib VERBOSE SMALLCODE SMALLDATA NODEBUG
- makedoc $file.c AUTODOC $file.doc BEGIN "/**LL******" END "******" CONVERTCOMMENTS
- delete $file.o
- cd /
- lha -r a Release:StdIO-Handler_v1.2.lha StdIO-Handler
- UnSet file
- Quit
- */
-
- /*
- ** $PROJECT: StdIO-Handler
- **
- ** $VER: StdIO-Handler.c 1.2 (05.04.95)
- **
- ** by
- **
- ** Stefan Ruppert , Windthorststraße 5 , 65439 Flörsheim , GERMANY
- **
- ** (C) Copyright 1995
- ** All Rights Reserved !
- **
- ** $HISTORY:
- **
- ** 05.04.95 : 001.002 : now I get the Process from the MsgPort structure
- ** 17.01.95 : 001.001 : works fine I think, also async
- ** 16.01.95 : 000.001 : initial
- */
-
- /*FS*/ /* $STARTDEFINE: "BumpRev defines"*/
- #define VERSION 1
- #define REVISION 2
- #define DATE "5.4.95"
- #define VERS "StdIO-Handler 1.2"
- #define VSTRING "StdIO-Handler 1.2 (5.4.95)\r\n"
- #define VERSTAG "\0$VER: StdIO-Handler 1.2 (5.4.95)"
- /*FE*/ /* $ENDDEFINE: */
-
- /*GB*** StdIO-Handler ********************************************************
-
- $VER: StdIO-Handler.doc
-
- NAME
- StdIO-Handler - Handler for StdIO access
-
- FUNCTION
- In december 1994 I got a PIPE package and I was very supprised about the
- easy implementation of these pipes. So I used this very often with gzip
- and tar. But after some tries, to use the pipes with standard Amiga CLI
- programs, I found no trick to redirect the input and output to the pipes.
- At this point I had a idea of writing a transparent handler. Thus the
- StdIO-Handler was born, using some example code from the Device-Handler
- by Matthias Scheler and Marius Gröger (Thanks for the available code !).
- The only thing you have to do, is to copy the STDIO file to your
- Devs:DosDrivers/ directory and the handler to your L: directory.
- After this you can use it like all other devices.
- Note: If you use this handler with the pipes, you can't use tools, which
- Seek's in the files (see the appropriate pipes doc) !
-
- Example Mount File :
-
- \* Standard-IO Handler *\
- Handler = L:StdIO-Handler
- Stacksize = 1000
- Priority = 5
- GlobVec = -1
-
-
- EXAMPLES
- Output the current direcory in sorted order :
- List | Sort Stdio: to Stdio:
-
- Output all files and subdirs last modified on august 1994 :
- List ALL | search stdio: Aug-94 NONUM
-
- List ALL | search stdio: -s--rw-d NONUM
-
- AUTHOR
- Stefan Ruppert
- Windthorststraße 5
- 65439 Flörsheim am Main
- GERMANY
- EMail: ruppert@vs3.informatik.fh-wiesbaden.de
-
- ******************************************************************************
- *
- */
-
- /*FS*/ /*"Includes"*/
- #include <exec/memory.h>
- #include <exec/execbase.h>
- #include <devices/trackdisk.h>
- #include <dos/dosextens.h>
- #include <dos/filehandler.h>
- #include <dos/dos.h>
-
- #define __USE_SYSBASE 42
-
- #include <clib/exec_protos.h>
- #include <pragmas/exec_pragmas.h>
-
- #include <clib/dos_protos.h>
- #include <pragmas/dos_pragmas.h>
-
- #include <clib/utility_protos.h>
- #include <pragmas/utility_pragmas.h>
-
- #include <string.h>
-
- #include <debug.h>
- #include <register.h>
- /*FE*/
-
- /*FS*/ /*"Structures"*/
- typedef struct GlobalData {
- struct Library *gd_SysBase;
- struct Library *gd_DOSBase;
- struct Library *gd_UtilityBase;
- struct MsgPort *gd_Port;
- struct MsgPort *gd_ReplyPort;
- struct DosList *gd_DosList;
- struct Process *gd_We;
- } *GD;
-
- struct StdIOData
- {
- struct StandardPacket Packet;
- struct MsgPort *Handler;
- struct DosPacket *Pkt;
- BPTR StdIO;
- };
-
- #define SysBase (gd->gd_SysBase)
- #define DOSBase (gd->gd_DOSBase)
- #define UtilityBase (gd->gd_UtilityBase)
- /*FE*/
-
- /*FS*/ /*"entry()"*/
- static ULONG main(void);
- static RegCall GetA4 ULONG entry(REGA0 UBYTE *line,REGD0 ULONG len)
- {
- return(main());
- }
- const static UBYTE version[]= VERSTAG;
- /*FE*/
-
- /*FS*/ static struct DosPacket *WaitDosPacket(GD gd, struct MsgPort *port)
- {
- WaitPort(port);
- return (struct DosPacket *)(GetMsg(port)->mn_Node.ln_Name);
- }
- /*FE*/
- /*FS*/ static void ReplyDosPacket(GD gd, struct MsgPort *port, struct DosPacket *Packet,LONG Res1,LONG Res2)
- {
- struct MsgPort *reply = Packet->dp_Port;
-
- ENTERING;
-
- Packet->dp_Port = port;
- Packet->dp_Link->mn_Node.ln_Name = (char *)Packet;
- Packet->dp_Res1 = Res1;
- Packet->dp_Res2 = Res2;
-
- PutMsg (reply, Packet->dp_Link);
-
- LEAVING;
- }
- /*FE*/
-
- /*FS*/ static void SendDosPacket(GD gd,struct DosPacket *Pkt)
- {
- struct StdIOData *stdio = (struct StdIOData *) Pkt->dp_Arg1;
-
- ENTERING;
-
- stdio->Pkt = Pkt;
-
- stdio->Packet.sp_Pkt.dp_Port = gd->gd_ReplyPort;
- stdio->Packet.sp_Pkt.dp_Res1 = 0;
- stdio->Packet.sp_Pkt.dp_Res2 = 0;
- stdio->Packet.sp_Pkt.dp_Arg2 = Pkt->dp_Arg2;
- stdio->Packet.sp_Pkt.dp_Arg3 = Pkt->dp_Arg3;
- PutMsg(stdio->Handler,&stdio->Packet.sp_Msg);
-
- LEAVING;
- }
- /*FE*/
-
- /*FS*/ static BOOL openres(GD gd)
- {
- BOOL rc = FALSE;
-
- DB(("entered\n"));
-
- DOSBase =
- UtilityBase = NULL;
-
- gd->gd_Port =
- gd->gd_ReplyPort = NULL;
-
- if (SysBase->lib_Version >= 37)
- {
- if (DOSBase = OpenLibrary("dos.library", 37))
- {
- if (UtilityBase = OpenLibrary("utility.library", 37))
- {
- if (gd->gd_Port = CreateMsgPort())
- {
- if(gd->gd_ReplyPort = CreateMsgPort())
- {
- rc = TRUE;
- } else
- DB(("no reply port\n"));
- }
- else DB(("no device port\n"));
- }
- else DB(("no utility V37\n"));
- }
- else DB(("no dos V37\n"));
- }
- else DB(("no exec V37\n"));
-
- DB(("left: %ld\n",rc));
-
- return rc;
- }
- /*FE*/
- /*FS*/ static void closeres(GD gd)
- {
- DB(("freeing port\n"));
- if (gd->gd_Port) DeleteMsgPort(gd->gd_Port);
-
- if (gd->gd_ReplyPort) DeleteMsgPort(gd->gd_ReplyPort);
-
- DB(("closing dos\n"));
- if (DOSBase) CloseLibrary(DOSBase);
-
- DB(("closing utility\n"));
- if (UtilityBase) CloseLibrary(UtilityBase);
- }
- /*FE*/
-
- /*FS*/ static ULONG main(void)
- {
- struct GlobalData GlobalData;
- struct GlobalData *gd;
-
- struct DosPacket *Pkt;
- BOOL Done;
- ULONG OpenCnt;
-
- gd = &GlobalData;
-
- DB(("Hello, this is the StdIO: Device\n"));
-
- SysBase = *(struct Library**)4L;
-
- if ((gd->gd_We = (struct Process *)FindTask(NULL))->pr_CLI) return RETURN_FAIL;
-
- DB(("waiting for startup-packet...\n"));
- Pkt = WaitDosPacket(gd, &gd->gd_We->pr_MsgPort);
-
- if (openres(gd))
- {
- struct Process *proc;
- struct FileHandle *fh;
- struct StdIOData *retio;
- ULONG portmask = (1<<gd->gd_Port->mp_SigBit);
- ULONG replymask = (1<<gd->gd_ReplyPort->mp_SigBit);
- ULONG recvd;
-
- gd->gd_DosList = (struct DosList *)BADDR(Pkt->dp_Arg3);
- gd->gd_DosList->dol_Task = gd->gd_Port;
-
- DB(("replying startup-packet...\n"))
- ReplyDosPacket(gd, gd->gd_Port, Pkt, DOSTRUE, Pkt->dp_Res2);
-
- Done=FALSE;
- OpenCnt=0L;
-
- DB(("entering mainloop\n"));
-
- while (!Done)
- {
- recvd = Wait(portmask | replymask);
-
- if(recvd & replymask)
- {
- while((retio = (struct StdIOData *) GetMsg(gd->gd_ReplyPort)))
- {
- LONG Bytes = retio->Packet.sp_Pkt.dp_Res1;
-
- DB(("replied stdiodata : %lx , Pkt : %lx\n",retio,retio->Pkt));
-
- if (Bytes < 0L)
- ReplyDosPacket(gd, gd->gd_Port,retio->Pkt, -1, retio->Packet.sp_Pkt.dp_Res2);
- else
- ReplyDosPacket(gd, gd->gd_Port,retio->Pkt, Bytes, 0);
- }
- }
-
- if(recvd & portmask)
- {
- struct Message *msg;
-
- while((msg = GetMsg(gd->gd_Port)))
- {
- Pkt = (struct DosPacket *) msg->mn_Node.ln_Name;
- DB(("got packet %ld\n",Pkt->dp_Type));
-
- Pkt->dp_Res1 = DOSFALSE;
- Pkt->dp_Res2 = ERROR_ACTION_NOT_KNOWN;
-
- switch (Pkt->dp_Type)
- {
- case ACTION_FINDINPUT:
- case ACTION_FINDOUTPUT:
- fh = BADDR(Pkt->dp_Arg1);
- fh->fh_Arg1 = 0L;
-
-
- proc = (struct Process *) Pkt->dp_Port->mp_SigTask;
- if((Pkt->dp_Port->mp_Flags == PA_SIGNAL) && (proc->pr_Task.tc_Node.ln_Type == NT_PROCESS))
- {
- struct StdIOData *stdio;
- if((stdio = AllocVec(sizeof(struct StdIOData),MEMF_ANY)))
- {
- if(Pkt->dp_Type == ACTION_FINDINPUT)
- {
- stdio->StdIO = proc->pr_CIS;
- stdio->Packet.sp_Pkt.dp_Type = ACTION_READ;
- } else
- {
- stdio->StdIO = proc->pr_COS;
- stdio->Packet.sp_Pkt.dp_Type = ACTION_WRITE;
- }
- fh = BADDR(stdio->StdIO);
- stdio->Handler = fh->fh_Type;
- stdio->Packet.sp_Pkt.dp_Link = &stdio->Packet.sp_Msg;
- stdio->Packet.sp_Pkt.dp_Arg1 = fh->fh_Arg1;
- stdio->Packet.sp_Msg.mn_Node.ln_Name = (STRPTR)&stdio->Packet.sp_Pkt;
- stdio->Packet.sp_Msg.mn_Node.ln_Type = NT_MESSAGE;
- stdio->Packet.sp_Msg.mn_Length = sizeof(struct StandardPacket);
- stdio->Packet.sp_Msg.mn_ReplyPort = gd->gd_ReplyPort;
-
- fh = BADDR(Pkt->dp_Arg1);
- fh->fh_Arg1 = (LONG) stdio;
-
- DB(("process : %s , stdio : %lx , type %ld \n",proc->pr_Task.tc_Node.ln_Name,stdio->StdIO,stdio->Packet.sp_Pkt.dp_Type));
- OpenCnt++;
- ReplyDosPacket(gd, gd->gd_Port,Pkt, DOSTRUE, 0);
- } else
- ReplyDosPacket(gd, gd->gd_Port,Pkt, DOSFALSE,ERROR_NO_FREE_STORE);
- } else
- ReplyDosPacket(gd, gd->gd_Port,Pkt, DOSFALSE,ERROR_OBJECT_NOT_FOUND);
- break;
- case ACTION_END:
- {
- struct StdIOData *stdio = (struct StdIOData *) Pkt->dp_Arg1;
-
- if(stdio)
- {
- OpenCnt--;
- FreeVec(stdio);
- ReplyDosPacket(gd, gd->gd_Port,Pkt, DOSTRUE, 0);
- }
- }
- break;
- case ACTION_WRITE:
- case ACTION_READ:
- {
- struct StdIOData *stdio = (struct StdIOData *)Pkt->dp_Arg1;
-
- if(stdio && stdio->Packet.sp_Pkt.dp_Type == Pkt->dp_Type)
- SendDosPacket(gd,Pkt);
- }
- break;
- case ACTION_IS_FILESYSTEM:
- ReplyDosPacket(gd, gd->gd_Port,Pkt, DOSFALSE, 0);
- break;
- case ACTION_SEEK:
- case ACTION_SET_FILE_SIZE:
- ReplyDosPacket(gd, gd->gd_Port,Pkt, -1,ERROR_ACTION_NOT_KNOWN);
- break;
- case ACTION_DIE:
- DB(("opencnt = %ld\n",OpenCnt));
-
- if (OpenCnt==0L)
- {
- if (IsListEmpty(&gd->gd_Port->mp_MsgList))
- {
- gd->gd_DosList->dol_Task = NULL;
-
- ReplyDosPacket(gd, gd->gd_Port,Pkt, DOSTRUE, 0);
-
- Done=TRUE;
- }
- else ReplyDosPacket(gd, gd->gd_Port,Pkt, DOSFALSE,ERROR_OBJECT_IN_USE);
- }
- else ReplyDosPacket(gd, gd->gd_Port,Pkt, DOSFALSE,ERROR_OBJECT_IN_USE);
- break;
- default:
- ReplyDosPacket(gd, gd->gd_Port, Pkt, DOSFALSE, ERROR_ACTION_NOT_KNOWN);
- break;
- }
- }
- }
- }
- }
- else
- ReplyDosPacket(gd, &gd->gd_We->pr_MsgPort, Pkt, DOSFALSE, ERROR_NO_FREE_STORE);
-
- closeres(gd);
-
- DB(("returning\n"));
-
- return(RETURN_OK);
- }
- /*FE*/
-
-